package org.ch02.job.test13;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 自动生成 SQL 语句 - 工具类
 *
 * @author ZQX
 * @date 2025-03-20
 */
public class SqlGenerate {
    /**
     * 基于 Bean 对象，生成查询所有字段的语句
     *
     * @param beanClass 实体对象（Bean）的 Class 对象
     * @return 查询所有字段的 SQL 语句
     */
    public static String generateSelect(Class<?> beanClass) {
        // select id,name from user
        StringBuilder sql = new StringBuilder("select ");

        // 获取实体对象所有的字段
        Field[] fields = beanClass.getDeclaredFields();
        for (Field field : fields) {
            // 把驼峰命名转换为数据规范命名
            sql.append(convertToSnake(field.getName())).append(",");
        }

        // 删除拼接最后一个字段后面的 ,
        sql.deleteCharAt(sql.length() - 1);
        sql.append(" from ");
        // 把驼峰命名转换为数据规范命名
        sql.append(convertToSnake(beanClass.getSimpleName()));
        return sql.toString();
    }

    /**
     * 方法重载 - 基于 Bean 对象，生成查询所有字段的语句，并且根据 Map 集合指定的参数拼接查询条件
     *
     * @param beanClass 实体对象的 Class 对象
     * @param cond      查询条件
     * @return 带条件且查询所有字段的SQL语句
     */
    public static String generateSelect(Class<?> beanClass, Map<String, Object> cond) {
        // 调用重载方法，获取查询所有字段的 SQL 语句
        StringBuilder sql = new StringBuilder(generateSelect(beanClass));

        if (cond == null && cond.size() == 0) {
            return sql.toString();
        }

        // where id=? and name=? and
        sql.append(" where ");

        for (String k : cond.keySet()) {
            sql.append(k).append("=?").append(" and ");
        }

        return sql.substring(0, sql.length() - 5);
    }


    /**
     * 实现把驼峰命名的字符串转换为数据的命名规范，如：
     * xxxXxxXxx - xxx_xxx_xxx
     * XxxXxxXxx - xxx_xxx_xxx
     *
     * @param input 驼峰命名的字符串
     * @return 数据规范命名的字符串
     */
    public static String convertToSnake(String input) {
        // 使用正则表达式替换，将大写字母前插入下划线，并将字符串转换为小写
        return input.replaceAll("(?<!^)([A-Z])", "_$1").toLowerCase();
    }

    public static String convertToCamel(String input) {
        // 使用正则表达式匹配下划线及其后的字母
        Pattern pattern = Pattern.compile("_([a-z])");
        Matcher matcher = pattern.matcher(input);
        StringBuffer sb = new StringBuffer();

        while (matcher.find()) {
            // 将下划线后的字母转换为大写
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);

        return sb.toString();
    }
}
